Centralt innehåll
- Skapande av klasser och objekt i ett objektorienterat programspråk utifrån tidigare analys och design.
1. Klasser & Objekt
Var inte orolig om du blir förvirrad av det här kapitlet. Klasser och objekt kan ta ett tag att förstå, men ofta blir det hela tydligt efter att man börjar skriva egna program som använder sig av det.
1.1 Procedurell programmering
Programmering handlar om att lösa problem. För att göra det har vi hittills mesta använt oss av procedurell programmering. Där försöker vi lösa ett visst problem genom att anropa funktioner.
1.2 Objektorienterad Programmering (OOP)
Programmering handlar också om att försöka få programmet så överskådligt och lättbegripligt som möjligt. Objektorienterad programmering (OOP) används för att modellera saker från den verkliga världen i kod. Det finns flera fördelar med det objektorienterade angreppssättet, koden blir bl.a enklare att underhålla (utöka, ändra, felsöka). De fördelarna uppnås framförallt i större projekt.
Objektorienterad programmering (OOP) är ett modernare sätt att skriva kod. OOP baseras på idén att gruppera egenskaper (attribut) och beteenden (metoder) till enheter av information, som kallas objekt.
2. Klasser
Klasser är väldigt användbart i programmering. Du använder dem hela tiden, utan att tänka på det. Vi har faktiskt redan använt några typer av klasser, t.ex. listor. Klasserna för listor är inbyggda i Python, och det finns massor av inbyggda klasser i Python man kan använda.
Klassen är mallen som används för att skapa ett verkligt objekt, t.ex. en lista med olika element (värden). En lista har ju värden och metoder kopplade till sig.
- En klass är en mall för att skapa objekt.
- Den verkliga förekomsten av en klass kallas objekt.
- Ibland kallas också objekt för instanser och att skapa objekt för att instansiera objekt.
2.1 Egna klasser
Klasserna för listor är inbyggda i Python, och det finns massor av inbyggda klasser man kan använda. Men nu ska vise hur man kan bygga sin egen klass med attribut och metoder.
Om man t.ex. ska skapa ett program som hanterar punkter i ett koordinatsystem och dess egenskaper som x, y värden är det bra att hålla ihop punktens värden. Då är det lämpligt att använda en klass.
En klass i Python skapas genom att använda nyckelordet class och ge det ett namn, som i det här exemplet:
class Punkt:
def __init__(self, x, y):
self.x = x
self.y = y
start_punkt = Punkt(3, -3) # Skapa ett objekt från klassen Punkt
print(f'Startpunkten har koordinaten {start_punkt.x}, {start_punkt.y}')
ger utskriften
Startpunkten har koordinaten 3, -3
Klassens namn skapas efter samma regler och med samma begränsningar som variabelnamn.
Praxis är att klassnamnet ska inledas med versal (stor bokstav) och vara singularis (ental).
Nyckelordet
self
referar till objektet självt. Koden self.x
innebär att attributet kopplas till objektet.
Uttrycket
start_punkt.x
betyder "gå till objektet start_punkt och hämta värdet för attributet x".
- En klass i Python skapas genom att använda nyckelordet
class
. - Praxis är att klassnamnet ska inledas med versal (stor bokstav) och vara singularis (ental).
2.2 Klasser vs Objekt
- För att skapa egna objekt måste man först skriva en klass.
- En klass är en mall/ritning av ett objekt. Klassen är mall för t.ex. hur en punkt ska se ut, och objektet är en faktisk punkt.
3. Konstruktor
För att kunna skapa mer flexibla klasser används något som kallas konstruktor. Konstruktorn används när objekt från en klass skapas. Det är här man ger objektet de värden som man önskar att objektet ska ha.
Konstruktorn är en särskild funktion som bara anropas när objektet skapas. Konstruktorn anropas endast en gång.
I Python har konstruktorn namnet __init__
. Du måste också definiera ett särskilt nyckelord,
self
, som en parameter till konstruktorn.
class Punkt:
def __init__(self, x, y): # The constructor
self.x = x # Attribute
self.y = y # Attribute
# Create objects from the class Punkt
start_punkt = Punkt(3, -3) # self is not given as an argument
slut_punkt = Punkt(4, 4)
print(f'Startpunkten har koordinaten {start_punkt.x}, {start_punkt.y}')
print(f'Slutpunkten har koordinaten {slut_punkt.x}, {slut_punkt.y}')
ger utskriften
Startpunkten har koordinaten (3, -3)
Slutpunkten har koordinaten (4, 4)
3.1 self
Nyckelordet self
refererar (pekar) till sig själv. Alla tilldelningar med nyckelordet
self
innebär att variabeln tillhör objektet.
Om man inte lägger till self
kommer det i stället att behandlas som en lokal variabel,
som ju är tillfällig, och som inte finns kvar efter att metoden __init()__
har körts.
För att visa hur self
fungerar kan du tänka på följande kod där tre variabler x, y och z,
tilldelas i __init__()
.
class Punkt:
def __init__(self, a, b, c):
self.x = a # Attributet hör till objektet
self.y = b # Attributet hör till objektet
z = c # En lokal variabel i konstruktorn
start_punkt = Punkt(3, 3, 1)
print(start_punkt.x)
print(start_punkt.y)
print(start_punkt.z) # Error, för att z tillhör inte objektet
ger utskriften 3 3Traceback (most recent call last): File "main.py", line 10, inprint(start_punkt.z) # Error, because z does not belong to the object AttributeError: 'Punkt' object has no attribute 'z'
- Konstruktorn används för att instansiera objekt, dvs skapa objekt.
- I Python heter konstruktorn
__init__
- Konstruktorn anropas automatiskt endast en gång när objektet skapas.
- Konstruktorn ger möjlighet att ange startvärden för attributen.
- Nyckelordet
self
refererar till objektet självt.
4. Metoder
Förutom egenskaper (attribut) kan klasser även ha beteende (metoder).
Många säger funktioner om metoder och tvärtom, vilket är ok och inte konstigt eftersom de är samma sak, men i lite olika sammanhang. Metoder är ju funktioner som är kopplade till objekt och man behöver ett objekt för att anropa metoderna.
- Funktionerna som hör till ett objekt kallas metoder.
- För att en funktion ska kallas en metod måste den definieras inuti klassen.
- Den första parametern i en metod ska alltid vara
self
.
class Punkt:
def __init__(self, x, y):
self.x = x
self.y = y
def distans_från_origo(self):
avstånd = ((self.x ** 2) + (self.y ** 2)) ** 0.5 # Pythagoras sats, upphöjt till 0.5 är samma som kvadroten
return avstånd
start_punkt = Punkt(3, 4) # Skapa ett objekt
avstånd = start_punkt.distans_från_origo() # Anropa objektets metod
print(avstånd)
ger utskriften
5.0
Vad blir utskriften med följande kod?
class Punkt:
def __init__(self, x, y):
self.x = x
self.y = y
def distans_från_origo(self):
avstånd = ((self.x ** 2) + (self.y ** 2)) ** 0.5 # Pythagoras sats, upphöjt till 0.5 är samma som kvadroten
return avstånd
start_punkt = Punkt(3, 4) # Skapa ett objekt
print(start_punkt)
ger utskriften
<__main__.Punkt object at 0x7f3298b71fa0>
Det är minnesadressen till objektet som skrivs ut, dvs var i minnet objektet lagras. Körs koden flera
gånger blir minnesadresserna olika.
Det finns en speciell metod __str__
som kan användas för att få en bättre utskrift än själva minnesadressen.
Den metoden anropas varje gång objektet försöker omvandla datatypen till en sträng, t.ex. när satsen
print(start_punkt)
körs. Metoden returnerar då en sträng, som i det här fallet används vid utskrift.
class Punkt:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
str = f'({self.x}, {self.y})'
return str
def distans_från_origo(self):
avstånd = ((self.x ** 2) + (self.y ** 2)) ** 0.5 # Pythagoras sats, upphöjt till 0.5 är samma som kvadroten
return avstånd
start_punkt = Punkt(3, 4) # Skapa ett objekt
print(start_punkt)
ger utskriften
(3, 4)
Metoder i klasser ska inte ha några egna utskrifter utan returnera värden. Klasserna blir då mer generella och flexibla och
kan återanvändas i flera olika projekt och program. Helt enkelt god design att göra på detta sätt.
Att många exempel och videos har utskrifter i metoder är för att visa hur olika koncept fungerar. I ett verkligt projekt
ska utskrifter undvikas från generella klasser. Speciella klasser som hanterar användrargränsnittet hanterar utskrifter.
Begrepp
Procedurell programmering: Lösa problem genom att anropa funktioner.
Objektorienterad programmering: Lösa problem genom att gruppera attribut och metoder i objekt.
Klass: En mall för att skapa objekt.
Objekt: En verklig förekomst av en klass.
Instans: Ett annat ord för objekt.
Instansiera: Skapa ett objekt.
Attribut: Variabler i en klass.
Metod: En funktion kopplad till ett objekt.
Konstruktor: En metod som automatiskt anropas när ett objekt skapas.